package cn.zcltd.btg.set.sourcemanager.db.dialect;

import cn.zcltd.btg.set.ParamSource;
import cn.zcltd.btg.set.core.Config;
import cn.zcltd.btg.set.core.Module;
import cn.zcltd.btg.set.core.Param;
import cn.zcltd.btg.set.sourcemanager.db.DbSourceManagerConfig;
import cn.zcltd.btg.set.util.DbUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 方言实现类
 */
public abstract class Dialect {
    protected final Logger log = LoggerFactory.getLogger(this.getClass());

    /**
     * 判断表是否存在
     *
     * @param conn      数据库连接
     * @param tableName 表名
     * @return 存在返回true，不存在返回false
     */
    public boolean tableIsExists(Connection conn, String tableName) {
        boolean isExists = false;
        try {
            DatabaseMetaData meta = conn.getMetaData();
            ResultSet rsTables = meta.getTables(null, null, tableName, new String[]{"TABLE"});
            isExists = rsTables.next();
            rsTables.close();
        } catch (SQLException e) {
            log.error(e.getMessage(), e);
        }
        return isExists;
    }

    /**
     * 删除表
     *
     * @param conn      数据库连接
     * @param tableName 表名
     */
    public void dropTable(Connection conn, String tableName) {
        String sql = "drop table " + tableName;
        DbUtil.executeUpdate(conn, sql);
        log.debug("drop table:" + tableName);
    }

    /**
     * 创建表Config
     *
     * @param conn      数据库连接
     * @param tableName 表名
     */
    public abstract void createTableConfig(Connection conn, String tableName);

    /**
     * 创建表Module
     *
     * @param conn      数据库连接
     * @param tableName 表名
     */
    public abstract void createTableModule(Connection conn, String tableName);

    /**
     * 创建表Param
     *
     * @param conn      数据库连接
     * @param tableName 表名
     */
    public abstract void createTableParam(Connection conn, String tableName);

    /**
     * 获取config列表
     *
     * @param conn                  数据库连接
     * @param dbSourceManagerConfig DbSourceManager配置
     * @return config列表
     */
    public List<Map<String, Object>> listConfig(Connection conn, DbSourceManagerConfig dbSourceManagerConfig) {
        String configTableName = dbSourceManagerConfig.getTablePrefix() + "_" + dbSourceManagerConfig.getConfigTableName();
        String sql = "select a.* from " + configTableName + " a";
        return DbUtil.executeQuery(conn, sql);
    }

    /**
     * 获取指定configId的param
     *
     * @param conn                  数据库连接
     * @param configId              configId
     * @param dbSourceManagerConfig DbSourceManager配置
     * @return param列表
     */
    public List<Map<String, Object>> listConfigParam(Connection conn, String configId, DbSourceManagerConfig dbSourceManagerConfig) {
        String paramTableName = dbSourceManagerConfig.getTablePrefix() + "_" + dbSourceManagerConfig.getParamTableName();
        String sql = "select a.* from " + paramTableName + " a where a.param_source = ? and a.config_id = ?";
        List<Object> params = new ArrayList<Object>();
        params.add("config");
        params.add(configId);
        return DbUtil.executeQuery(conn, sql, params.toArray());
    }

    /**
     * 获取指定configId的module
     *
     * @param conn                  数据库连接
     * @param configId              configId
     * @param dbSourceManagerConfig DbSourceManager配置
     * @return module列表
     */
    public List<Map<String, Object>> listConfigModule(Connection conn, String configId, DbSourceManagerConfig dbSourceManagerConfig) {
        String moduleTableName = dbSourceManagerConfig.getTablePrefix() + "_" + dbSourceManagerConfig.getModuleTabletable();
        String sql = "select a.* from " + moduleTableName + " a where a.config_id = ?";
        List<Object> params = new ArrayList<Object>();
        params.add(configId);
        return DbUtil.executeQuery(conn, sql, params.toArray());
    }

    /**
     * 获取指定configId下moduleId的param
     *
     * @param conn                  数据库连接
     * @param configId              configId
     * @param moduleId              moduleId
     * @param dbSourceManagerConfig DbSourceManager配置
     * @return param列表
     */
    public List<Map<String, Object>> listModuleParam(Connection conn, String configId, String moduleId, DbSourceManagerConfig dbSourceManagerConfig) {
        String paramTableName = dbSourceManagerConfig.getTablePrefix() + "_" + dbSourceManagerConfig.getParamTableName();
        String sql = "select a.* from " + paramTableName + " a where a.param_source = ? and a.config_id = ? and a.module_id = ?";
        List<Object> params = new ArrayList<Object>();
        params.add("module");
        params.add(configId);
        params.add(moduleId);
        return DbUtil.executeQuery(conn, sql, params.toArray());
    }

    /**
     * 获取指定configId
     *
     * @param conn                  数据库连接
     * @param configId              configId
     * @param dbSourceManagerConfig DbSourceManager配置
     * @return config
     */
    public Map<String, Object> mapConfig(Connection conn, String configId, DbSourceManagerConfig dbSourceManagerConfig) {
        String configTableName = dbSourceManagerConfig.getTablePrefix() + "_" + dbSourceManagerConfig.getConfigTableName();
        String sql = "select a.* from " + configTableName + " a where a.config_id = ?";
        List<Object> params = new ArrayList<Object>();
        params.add(configId);
        List<Map<String, Object>> configList = DbUtil.executeQuery(conn, sql, params.toArray());
        if (configList.size() > 0) {
            return configList.get(0);
        }
        return null;
    }

    /**
     * 清除指定配置
     *
     * @param conn                  数据库连接
     * @param configId              configId
     * @param dbSourceManagerConfig DbSourceManager配置
     */
    public void clearConfig(Connection conn, String configId, DbSourceManagerConfig dbSourceManagerConfig) {
        String sql;
        List<Object> params;

        String configTableName = dbSourceManagerConfig.getTablePrefix() + "_" + dbSourceManagerConfig.getConfigTableName();
        sql = "delete from " + configTableName + " where config_id = ?";
        params = new ArrayList<Object>();
        params.add(configId);
        DbUtil.executeUpdate(conn, sql, params.toArray());

        String moduleTableName = dbSourceManagerConfig.getTablePrefix() + "_" + dbSourceManagerConfig.getModuleTabletable();
        sql = "delete from " + moduleTableName + " where config_id = ?";
        params = new ArrayList<Object>();
        params.add(configId);
        DbUtil.executeUpdate(conn, sql, params.toArray());

        String paramTableName = dbSourceManagerConfig.getTablePrefix() + "_" + dbSourceManagerConfig.getParamTableName();
        sql = "delete from " + paramTableName + " where config_id = ?";
        params = new ArrayList<Object>();
        params.add(configId);
        DbUtil.executeUpdate(conn, sql, params.toArray());
    }

    /**
     * 插入config
     *
     * @param conn                  数据库连接
     * @param config                config对象
     * @param dbSourceManagerConfig DbSourceManager配置
     * @return int
     */
    public int insertConfig(Connection conn, Config config, DbSourceManagerConfig dbSourceManagerConfig) {
        String configTableName = dbSourceManagerConfig.getTablePrefix() + "_" + dbSourceManagerConfig.getConfigTableName();
        String sql = "insert into " + configTableName + "(config_id,config_name,config_desc) values(?,?,?)";
        List<Object> params = new ArrayList<Object>();
        params.add(config.getId());
        params.add(config.getName());
        params.add(config.getDesc());
        return DbUtil.executeUpdate(conn, sql, params.toArray());
    }

    /**
     * 插入module
     *
     * @param conn                  数据库连接
     * @param module                module对象
     * @param dbSourceManagerConfig DbSourceManager配置
     * @return int
     */
    public int insertModule(Connection conn, Module module, DbSourceManagerConfig dbSourceManagerConfig) {
        String moduleTableName = dbSourceManagerConfig.getTablePrefix() + "_" + dbSourceManagerConfig.getModuleTabletable();
        String sql = "insert into " + moduleTableName + "(config_id,module_id,module_name,module_desc) values(?,?,?,?)";
        List<Object> params = new ArrayList<Object>();
        params.add(module.getConfig().getId());
        params.add(module.getId());
        params.add(module.getName());
        params.add(module.getDesc());
        return DbUtil.executeUpdate(conn, sql, params.toArray());
    }

    /**
     * 插入param
     *
     * @param conn                  数据库连接
     * @param configType            param类型
     * @param param                 param对象
     * @param dbSourceManagerConfig DbSourceManager配置
     * @return int
     */
    public int insertParam(Connection conn, ParamSource configType, Param param, DbSourceManagerConfig dbSourceManagerConfig) {
        String paramTableName = dbSourceManagerConfig.getTablePrefix() + "_" + dbSourceManagerConfig.getParamTableName();
        String sql = "insert into " + paramTableName + "(config_id,module_id,param_id,param_source,param_type,param_date_pattern,param_name,param_value,param_desc,param_remark) values(?,?,?,?,?,?,?,?,?,?)";
        List<Object> params = new ArrayList<Object>();
        params.add(param.getConfig().getId());
        if (configType.equals(ParamSource.CONFIG)) {
            params.add(param.getConfig().getId());
        } else if (configType.equals(ParamSource.MODULE)) {
            params.add(param.getModule().getId());
        }
        params.add(param.getId());
        params.add(param.getSource().getCode());
        params.add(param.getType().getName());
        params.add(param.getDatePattern());
        params.add(param.getName());
        params.add(param.getValue());
        params.add(param.getDesc());
        params.add(param.getRemark());
        return DbUtil.executeUpdate(conn, sql, params.toArray());
    }
}